package com.xxx.car.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xxx.car.biz.SmsService;
import com.xxx.car.cache.CarRedisTemplate;
import com.xxx.car.entity.TbBanner;
import com.xxx.car.entity.TbUser;
import com.xxx.car.entity.TbUserExample;
import com.xxx.car.entity.vo.AppUserCacheInfo;
import com.xxx.car.entity.vo.request.ReqAdminLogin;
import com.xxx.car.entity.vo.request.ReqUserAdminQuery;
import com.xxx.car.entity.vo.request.ReqUserLogin;
import com.xxx.car.entity.vo.request.ReqUserRegister;
import com.xxx.car.entity.vo.response.RespUserLogin;
import com.xxx.car.mapper.ITbMapper;
import com.xxx.car.mapper.TbSmsContentMapper;
import com.xxx.car.mapper.TbUserMapper;
import com.xxx.car.redisCluster.utils.JsonUtil;
import com.xxx.car.service.CommonService;
import com.xxx.car.service.UserService;
import com.xxx.car.utils.DataEncryptionUtils;
import com.xxx.car.utils.DateUtils;
import com.xxx.car.utils.GsonUtils;
import com.xxx.car.utils.ShareCodeUtil;
import com.xxx.common.base.exception.BizException;
import com.xxx.common.base.vo.APIResponse;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.List;

/**
 * Created by yxj on 17/6/15.
 */
@Service
public class UserServiceImpl implements UserService {
	private final static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
	@Autowired
	CarRedisTemplate carRedisTemplate;
	@Autowired
	TbUserMapper tbUserMapper;
	@Autowired
	SmsService smsService;
	@Autowired
	TbSmsContentMapper tbSmsContentMapper;
	@Autowired
	CommonService commonService;
	@Autowired
	ITbMapper iTbUserMapper;

	@Override
	public void sendValidCodetToPhone(String phone, int resend, int exp) {
		smsService.sendValidCodetToPhone(phone, resend ,exp);
	}

	@Override
	public APIResponse<?> userRegister(ReqUserRegister reqUserRegister) {
		//检查用户是否存在
		String phone = reqUserRegister.getMobile();
		if (StringUtils.isEmpty(phone)){
			return APIResponse.returnFail("手机号必填");
		}
		if (StringUtils.isEmpty(reqUserRegister.getValidCode())){
			return APIResponse.returnFail("验证码必填");
		}
		boolean isValid = smsService.verifyValidCode(phone, reqUserRegister.getValidCode());
		if (!isValid){
			return APIResponse.returnFail("验证码错误");
		}
		TbUser dbUser = getTbUserByPhone(phone);
		if (dbUser != null){
			return APIResponse.returnFail("用户已经注册");
		}
		TbUser tbUser = new TbUser();

		tbUser.setMobile(reqUserRegister.getMobile());
		tbUser.setPassword(reqUserRegister.getPassword());
		tbUser.setGroupId(1);//APP用户
		tbUser.setIsDelete((byte)0);
		tbUserMapper.insertSelective(tbUser);
		List<TbUser> tbUserList = iTbUserMapper.getAppUserByMobile(reqUserRegister.getMobile());
		if (tbUserList != null && tbUserList.size() != 0) {
			String userCookieName = commonCookies(null,tbUser.getId(),phone);
			RespUserLogin respUserLogin = new RespUserLogin();
			respUserLogin.setTbUser(tbUserList.get(0));
			respUserLogin.setUserCookieName(userCookieName);
			return APIResponse.returnSuccess(respUserLogin);
		} else {
			return APIResponse.returnFail("网络异常");
		}
	}

	@Override
	public APIResponse userLogin(ReqUserLogin reqUserLogin) {
		//检查用户是否存在
		String phone = reqUserLogin.getMobile();
		if (StringUtils.isEmpty(phone)){
			return APIResponse.returnFail("手机号必填");
		}
		TbUser dbUser = getTbUserByPhone(phone);
		if (dbUser == null){
			return APIResponse.returnFail("用户不存在");
		}
		if (dbUser.getMobile().equals(reqUserLogin.getMobile()) &&
				dbUser.getPassword().equals(reqUserLogin.getPassword())){
			if (dbUser.getIsDelete().equals((byte)1)){
				return APIResponse.returnFail("用户已被停用");
			}
			String userCookieName = commonCookies(null,dbUser.getId(),dbUser.getMobile());
			RespUserLogin respUserLogin = new RespUserLogin();
			respUserLogin.setTbUser(dbUser);
			respUserLogin.setUserCookieName(userCookieName);
			return APIResponse.returnSuccess(respUserLogin);
		} else if(!dbUser.getMobile().equals(reqUserLogin.getMobile())){
			return APIResponse.returnFail("用户名不正确");
		} else if(!dbUser.getPassword().equals(reqUserLogin.getPassword())){
			return APIResponse.returnFail("密码不正确");
		}
		return APIResponse.returnFail("用户名或密码不正确");
	}

	/**
	 * 退出登录
	 */
	@Override
	public APIResponse logout(String userCookieName) {
		//重新生成userCookiesName  --游客模式
		String newUserCookieName = commonCookies(userCookieName,0,"1");
		return APIResponse.returnSuccess(newUserCookieName);
	}

	/**
	 * 编辑用户头像
	 * @param file
	 * @param userId
	 * @return
	 */
	@Override
	public APIResponse uploadUserIcon(MultipartFile file, Integer userId) {
		if (null == userId){
			return APIResponse.returnFail("userId不能为空");
		}
		String fileName = null;
		try {
			fileName = commonService.uploadFile(file);
		} catch (Exception e) {
			return APIResponse.returnFail("头像上传失败,请重试");
		}
		TbUser tbUser = new TbUser();
		tbUser.setId(userId);
		tbUser.setIcon(fileName);
		tbUserMapper.updateByPrimaryKeySelective(tbUser);
		return APIResponse.returnSuccess(tbUser);
	}

	/**
	 * 修改用户昵称
	 * @param nickName
	 * @param userId
	 * @return
	 */
	@Override
	public APIResponse modifyUserNickName(String nickName, Integer userId) {
		if (null == userId){
			return APIResponse.returnFail("userId不能为空");
		}
		TbUser tbUser = new TbUser();
		tbUser.setId(userId);
		tbUser.setLoginName(nickName);
		int result = tbUserMapper.updateByPrimaryKeySelective(tbUser);
		if (result == 1){
			return APIResponse.returnSuccess();
		}
		return APIResponse.returnFail("请重试");
	}

	@Override
	public APIResponse userDetail(Integer userId) {
		TbUser tbUser = tbUserMapper.selectByPrimaryKey(userId);
		return APIResponse.returnSuccess(tbUser);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
	public APIResponse modifyUserPassword(String phone, String password) throws Exception{
		TbUser dbUser = getTbUserByPhone(phone);
		if (dbUser.getIsDelete().equals((byte)1)){
			return APIResponse.returnFail("用户已被停用");
		}
		int result = iTbUserMapper.modifyUserPassword(password,phone);
		if (result != 1) {
			throw new BizException("修改密码失败");
		}
		String userCookieName = commonCookies(null,dbUser.getId(),dbUser.getMobile());
		RespUserLogin respUserLogin = new RespUserLogin();
		respUserLogin.setTbUser(dbUser);
		respUserLogin.setUserCookieName(userCookieName);
		return APIResponse.returnSuccess(respUserLogin);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
	public APIResponse passwordLost(ReqUserRegister reqUserRegister) throws Exception{
		boolean isValid = smsService.verifyValidCode(reqUserRegister.getMobile(), reqUserRegister.getValidCode());
		if (!isValid){
			return APIResponse.returnFail("验证码错误");
		}
		try {
			return this.modifyUserPassword(reqUserRegister.getMobile(),reqUserRegister.getPassword());
		} catch (Exception e) {
			throw e;
		}
	}

	@Override
	public APIResponse getShareCode(Integer userId) {
		String shareCode = ShareCodeUtil.toSerialCode(Long.parseLong(userId.toString()));
		return APIResponse.returnSuccess(shareCode);
	}

	@Override
	public PageInfo<?> queryAppUserListByAdmin(ReqUserAdminQuery query) {
		PageHelper.startPage(query.getPageNum(), query.getPageSize());
		List<TbUser> tbUserList= iTbUserMapper.queryAppUserListByAdmin(query);
		return new PageInfo<>(tbUserList);
	}

	@Override
	public Integer queryAppNormalUserCount() {
		return iTbUserMapper.queryAppNormalUserCount();
	}

	@Override
	public Integer queryAppFrozenUserCount() {
		return iTbUserMapper.queryAppFrozenUserCount();
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
	public APIResponse modifyUser(Integer userId, String nickName, String password, Integer isDelete, Integer groupId) {
		TbUser tbUser = new TbUser();
		tbUser.setId(userId);
		tbUser.setLoginName(nickName);
		tbUser.setPassword(password);
		if (null != groupId) {
			tbUser.setGroupId(groupId);
		}
		if (null != isDelete) {
			tbUser.setIsDelete(isDelete.byteValue());
		}
		int result = tbUserMapper.updateByPrimaryKeySelective(tbUser);
		if (result != 1) {
			throw new BizException("更新失败");
		}
		return APIResponse.returnSuccess();
	}

	@Override
	public PageInfo<?> queryAdminUserListByAdmin(ReqUserAdminQuery query) {
		PageHelper.startPage(query.getPageNum(), query.getPageSize());
		List<TbBanner> tbUserList= iTbUserMapper.queryAdminUserListByAdmin(query);
		return new PageInfo<>(tbUserList);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
	public APIResponse addAdminUser(String loginName, String password, Integer groupId) {
		TbUser tbUser = new TbUser();
		tbUser.setLoginName(loginName);
		tbUser.setPassword(password);
		tbUser.setGroupId(groupId);
		tbUser.setIsDelete((byte)0);
		int result = tbUserMapper.insertSelective(tbUser);
		if (result != 1){
			throw new BizException("添加失败");
		}
		return APIResponse.returnSuccess();
	}

	@Override
	public TbUser queryUserByMobile(String mobile) {
		List<TbUser> tbUserList = iTbUserMapper.getAppUserByMobile(mobile);
		if (tbUserList != null && tbUserList.size() != 0) {
			return tbUserList.get(0);
		}
		return null;
	}

	@Override
	public APIResponse adminUserLogin(ReqAdminLogin reqAdminLogin) {
		//检查用户是否存在
		String username = reqAdminLogin.getUsername();
		if (StringUtils.isEmpty(username)){
			return APIResponse.returnFail("用户名必填");
		}
		TbUser dbUser = getTbUserByUserName(username);
		if (dbUser == null){
			return APIResponse.returnFail("用户不存在");
		}
		if (dbUser.getLoginName().equals(reqAdminLogin.getUsername()) &&
				dbUser.getPassword().equals(reqAdminLogin.getPassword())){
			if (dbUser.getIsDelete().equals((byte)1)){
				return APIResponse.returnFail("用户已被停用");
			}
			return APIResponse.returnSuccess(dbUser);
		} else if(!dbUser.getLoginName().equals(reqAdminLogin.getUsername())){
			return APIResponse.returnFail("用户名不正确");
		} else if(!dbUser.getPassword().equals(reqAdminLogin.getPassword())){
			return APIResponse.returnFail("密码不正确");
		}
		return APIResponse.returnFail("用户名或密码不正确");
	}


	public TbUser getTbUserByPhone(String phone){
		String mobile = phone.trim();
		TbUserExample tbUserExample = new TbUserExample();
		TbUserExample.Criteria criteria = tbUserExample.createCriteria();
		criteria.andMobileEqualTo(mobile);
		List<TbUser> tbUserList = iTbUserMapper.getAppUserByMobile(phone);
		return CollectionUtils.isEmpty(tbUserList)?null:tbUserList.get(0);
	}

	public TbUser getTbUserByUserName(String username){
		String userName = username.trim();
		List<TbUser> tbUserList = iTbUserMapper.getAdminUserByUserName(userName);
		return CollectionUtils.isEmpty(tbUserList)?null:tbUserList.get(0);
	}

	/**
	 * 公共cookies生成
	 * @param userCookiesName 用户cookies
	 * @param uid 用户ID
	 * @return 用户cookies名称
	 */
	public String commonCookies(String userCookiesName,Integer uid,String phone){
		String cookies;
		AppUserCacheInfo appUserCacheInfo;
		if (StringUtils.isBlank(userCookiesName)) {
			appUserCacheInfo = new AppUserCacheInfo();
			appUserCacheInfo.setUid(uid);
			appUserCacheInfo.setUpdateTime(DateUtils.getSecondTimestampOne(new Date()));
			appUserCacheInfo.setPhone(phone);
			cookies = DataEncryptionUtils.SHA1(appUserCacheInfo.toString());
		} else {
			cookies = userCookiesName;
			try {
				Object redisUsg = carRedisTemplate.get(userCookiesName);
				appUserCacheInfo =(AppUserCacheInfo) JsonUtil.parseJsonStr2Object(redisUsg.toString(),AppUserCacheInfo.class);
				if (appUserCacheInfo != null) {
					appUserCacheInfo.setUid(uid);
					appUserCacheInfo.setUpdateTime(DateUtils.getSecondTimestampOne(new Date()));
					appUserCacheInfo.setPhone(phone);
				} else {
					appUserCacheInfo = new AppUserCacheInfo();
					appUserCacheInfo.setUid(uid);
					appUserCacheInfo.setUpdateTime(DateUtils.getSecondTimestampOne(new Date()));
					appUserCacheInfo.setPhone(phone);
				}
			} catch (Exception e) {
				logger.error("获取用户cookies失败：uid为：【{}】；userCookiesName为：{}；异常信息为：{}",uid,userCookiesName,e);
				appUserCacheInfo = new AppUserCacheInfo();
				appUserCacheInfo.setUid(uid);
				appUserCacheInfo.setUpdateTime(DateUtils.getSecondTimestampOne(new Date()));
				appUserCacheInfo.setPhone(phone);
			}
		}
		carRedisTemplate.save(cookies, GsonUtils.toJson(appUserCacheInfo),0);
		return cookies;
	}

	public static void main(String[] args) {
		long uid = ShareCodeUtil.codeToId("xobv5q");
		System.out.print(uid);
	}
}
